/* translate.h */
#ifndef __TRANSLATE_H__
#define __TRANSLATE_H__

typedef struct Tr_level_ *Tr_level;
typedef struct Tr_access_ *Tr_access;
typedef struct Tr_accessList_ *Tr_accessList;

struct Tr_level_
{
	Tr_level parent;
	F_frame frame;
	Tr_accessList formals;
	Tr_accessList locals;
};

struct Tr_access_ { 
	Tr_level level; 
	F_access access; 
};

struct Tr_accessList_ { 
	Tr_access head; 
	Tr_accessList tail; 
};

Tr_access Tr_Access(Tr_level level, F_access acs);
Tr_accessList Tr_AccessList(Tr_access head, Tr_accessList tail);


typedef struct patchList_ *patchList;
struct patchList_ {Temp_label *head; patchList tail; };

typedef struct Tr_exp_ * Tr_exp;

typedef struct Cx_ *Cx; 
struct Cx_
{
	patchList trues;
	patchList falses;
	T_stm stm;
};

struct Tr_exp_
{
	enum { TR_EX, TR_NX, TR_CX } kind;
	union { T_exp ex; T_stm nx; struct Cx_ cx; } u;
};

typedef struct Tr_expList_ *Tr_expList;
struct Tr_expList_{
	Tr_exp head;
	Tr_expList tail;
};
Tr_expList Tr_ExpList(Tr_exp head, Tr_expList tail);

Tr_level Tr_newLevel(Tr_level parent, Temp_label name, F_accessList formals);
Tr_level Tr_outermost(void);
Tr_accessList Tr_formals(Tr_level level);
Tr_access Tr_allocLocal(Tr_level level, bool escape);

F_frame Tr_levelframe(Tr_level level);


Tr_exp Tr_Num(int num);
Tr_exp Tr_String(string str);
Tr_exp Tr_Call(Tr_level level, Temp_label label, Tr_expList args);
Tr_exp Tr_Op(int op, Tr_exp left, Tr_exp right);
Tr_exp Tr_Rel(int op, Tr_exp left, Tr_exp right);
Tr_exp Tr_StringRel(int op, Tr_exp left, Tr_exp right);
Tr_exp Tr_Record(Tr_expList fields, int size);
Tr_exp Tr_Array(Tr_exp size, Tr_exp init);
Tr_exp Tr_Seq(T_stmList stms);
Tr_exp Tr_If(Tr_exp cond, Tr_exp thenc, Tr_exp elsec);
Tr_exp Tr_While(Tr_exp cond, Tr_exp body);
Tr_exp Tr_For(Tr_access access, Tr_exp low, Tr_exp high, Tr_exp body);
Tr_exp Tr_Assign(Tr_exp left, Tr_exp rexp);
Tr_exp Tr_SimpleVar(Tr_access access, Tr_level level);
Tr_exp Tr_FieldVar(Tr_exp record, int index);
void Tr_printExp(Tr_exp exp);

#endif //!__TRANSLATE_H__